package cn.kent.high.juc.lock.aqs;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * AQS的条件变量 测试类
 *
 *
 */
public class AqsCondition {
    public static final ReentrantLock lock = new ReentrantLock();
    // 创建条件变量，一个Lock对象可以创建多个条件变量
    // ConditionObject是AQS的一个内部类，可以获取AQS的一些状态信息。
    private static final Condition condition = lock.newCondition();

    public static void main(String[] args) {
        lock.lock();
        try {
            System.out.println("begin wait");
            // 同Object的wait方法，如果在没有获取到锁前调用条件变量的await方法，会抛出异常 IllegalMonitorStateException
            condition.await();
            System.out.println("end wait");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        lock.lock();
        try {
            System.out.println("begin signal");
            condition.signal();
            System.out.println("end signal");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        /**
         * public final void await() throws InterruptedException {
         *             if (Thread.interrupted())
         *                 throw new InterruptedException();
         *             // 创建新的node节点，并插入到条件队列末尾
         *             Node node = addConditionWaiter();
         *             // 释放当前获取的锁
         *             int savedState = fullyRelease(node);
         *             int interruptMode = 0;
         *             // 调用park方法阻塞 挂起当前线程
         *             while (!isOnSyncQueue(node)) {
         *                 LockSupport.park(this);
         *                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
         *                     break;
         *             }
         *             if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
         *                 interruptMode = REINTERRUPT;
         *             if (node.nextWaiter != null) // clean up if cancelled
         *                 unlinkCancelledWaiters();
         *             if (interruptMode != 0)
         *                 reportInterruptAfterWait(interruptMode);
         *         }
         *
         *         public final void signal() {
         *             if (!isHeldExclusively())
         *                 throw new IllegalMonitorStateException();
         *             Node first = firstWaiter;
         *             if (first != null)
         *                 // 将队列头元素移动到aqs队列
         *                 doSignal(first);
         *         }
         */
    }
}
